#include <iostream>       // 标准输入输出流
#include <thread>         // 多线程支持
#include <future>         // 异步操作支持（promise/future）

// 使用promise和future实现线程间数据传递
void Add(int num1, int num2, std::promise<int> &prom) 
{
    // 模拟耗时操作（3秒）
    std::this_thread::sleep_for(std::chrono::seconds(3)); 
    
    // 将计算结果设置到promise对象中
    prom.set_value(num1 + num2);  // 触发关联future的就绪状态
    
    // 注意：promise的set_value只能调用一次
    return;
}

int main() 
{
    // 创建promise对象（用于生产者线程设置值）
    std::promise<int> prom;
    
    // 获取与promise关联的future对象（用于消费者线程获取值）
    std::future<int> fu = prom.get_future();  // 每个promise对应唯一future
    
    // 启动工作线程（注意必须用std::ref传递引用）
    std::thread thr(Add, 11, 22, std::ref(prom));  
    // std::ref的作用：promise不可拷贝，必须通过引用传递
    
    // 主线程阻塞等待结果（若子线程未set_value会永久阻塞）
    int res = fu.get();  // 此处会等待直到promise设置值
    std::cout << "计算结果: " << res << std::endl;  // 输出33
    
    // 等待工作线程结束（保证线程安全退出）
    thr.join();  
    
    return 0;
}

/*
代码执行流程：
1. 主线程创建promise和future
2. 启动子线程执行Add函数
3. 子线程休眠3秒 → 主线程在fu.get()处阻塞等待
4. 子线程设置计算结果 → 主线程恢复执行
5. 主线程输出结果并等待子线程结束

关键机制说明：
1. promise/future绑定：
   - 一个promise对应一个future
   - set_value()和get()形成跨线程通信通道

2. 线程同步：
   - future.get()会自动实现线程间同步
   - 无需手动使用条件变量或互斥锁

潜在风险：
1. 死锁风险：
   - 如果子线程未调用set_value，主线程将永久阻塞在get()
   
2. 多次设置值：
   - promise只能set_value一次，重复调用会抛std::future_error

3. 线程未join：
   - 如果子线程抛出异常未join，可能导致资源泄漏
*/

/* 建议改进方向：
1. 添加异常处理：
   try {
       // 启动线程
   } catch (...) {
       prom.set_exception(std::current_exception());
   }

2. 使用RAII管理线程：
   std::jthread（C++20）可自动join

3. 设置超时等待：
   if(fu.wait_for(5s) == std::future_status::ready) {
       // 获取结果
   }
*/